#ifndef MY_LOGGER_HPP
#define MY_LOGGER_HPP

#include <log4cpp/Category.hh>
#include <log4cpp/Appender.hh>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/OstreamAppender.hh>
#include <log4cpp/Priority.hh>
#include <log4cpp/PatternLayout.hh>
#include <log4cpp/PropertyConfigurator.hh>
#include <log4cpp/RollingFileAppender.hh>
#include <mutex>
#include <string>
#include <sstream>

class MyLogger {
public:
    // 获取单例实例（线程安全）
    static MyLogger* getInstance() {
        std::call_once(initFlag, [] { instance = new MyLogger(); });
        return instance;
    }

    // 销毁单例
    static void destroy() {
        if (instance) {
            delete instance;
            instance = nullptr;
        }
    }

    /* // 初始化日志系统（使用配置文件） */
    /* bool init(const std::string& configFile) { */
    /*     try { */
    /*         log4cpp::PropertyConfigurator::configure(configFile); */
    /*         category = &log4cpp::Category::getRoot(); */
    /*         return true; */
    /*     } catch (log4cpp::ConfigureFailure& e) { */
    /*         std::cerr << "Log config failed: " << e.what() << std::endl; */
    /*         return false; */
    /*     } */
    //}
    // 默认初始化（控制台+文件输出）
    void defaultInit() {
        // 控制台输出
        category = &log4cpp::Category::getRoot();
        log4cpp::Appender* consoleAppender = new log4cpp::OstreamAppender("console", &std::cout);
        log4cpp::PatternLayout* consoleLayout = new log4cpp::PatternLayout();
        consoleLayout->setConversionPattern("%d [%p] %m%n");
        consoleAppender->setLayout(consoleLayout);
        // 文件输出（自动回卷）
        log4cpp::Appender* fileAppender = new log4cpp::RollingFileAppender("fileAppender", "./log/server.log", 10 * 1024 * 1024, 5);
        log4cpp::PatternLayout* fileLayout = new log4cpp::PatternLayout();
        fileLayout->setConversionPattern("%d [%p] [%c] %m%n");
        fileAppender->setLayout(fileLayout);

        // 创建分类并添加输出器
        category = &log4cpp::Category::getInstance("MyLogger");
        category->addAppender(consoleAppender);
        category->addAppender(fileAppender);
        category->setPriority(log4cpp::Priority::DEBUG);
    }

    // 日志记录方法（支持可变参数）
    template<typename... Args>
    void error(const char* file, int line, const char* func, const char* fmt, Args... args) {
        log(log4cpp::Priority::ERROR, file, line, func, fmt, args...);
    }

    template<typename... Args>
    void warn(const char* file, int line, const char* func, const char* fmt, Args... args) {
        log(log4cpp::Priority::WARN, file, line, func, fmt, args...);
    }

    template<typename... Args>
    void info(const char* file, int line, const char* func, const char* fmt, Args... args) {
        log(log4cpp::Priority::INFO, file, line, func, fmt, args...);
    }

    template<typename... Args>
    void debug(const char* file, int line, const char* func, const char* fmt, Args... args) {
        log(log4cpp::Priority::DEBUG, file, line, func, fmt, args...);
    }

private:
    MyLogger() { defaultInit(); }
    ~MyLogger() { 
        if(category) category->shutdown(); 
    }

    // 禁止拷贝
    MyLogger(const MyLogger&) = delete;
    MyLogger& operator=(const MyLogger&) = delete;

    // 核心日志记录函数
    template<typename... Args>
    void log(log4cpp::Priority::PriorityLevel level, 
             const char* file, int line, const char* func, 
             const char* fmt, Args... args) {
        if (!category) return;
        char buffer[1024];
        snprintf(buffer, sizeof(buffer), "[%s:%d %s] %s", file, line, func, fmt);
        category->log(level, buffer, args...);
    }

    static MyLogger* instance;
    static std::once_flag initFlag;
    log4cpp::Category* category = nullptr;
};

// 静态成员初始化
MyLogger* MyLogger::instance = nullptr;
std::once_flag MyLogger::initFlag;

// 日志宏（自动捕获文件/行号/函数名）
#define LOG_ERROR(fmt, ...) \
    MyLogger::getInstance()->error(__FILE__, __LINE__, __func__, fmt, ##__VA_ARGS__)

#define LOG_WARN(fmt, ...) \
    MyLogger::getInstance()->warn(__FILE__, __LINE__, __func__, fmt, ##__VA_ARGS__)

#define LOG_INFO(fmt, ...) \
    MyLogger::getInstance()->info(__FILE__, __LINE__, __func__, fmt, ##__VA_ARGS__)

#define LOG_DEBUG(fmt, ...) \
    MyLogger::getInstance()->debug(__FILE__, __LINE__, __func__, fmt, ##__VA_ARGS__)

#endif // MY_LOGGER_HPP
